// tasks
package tasks

import (
	"encoding/json"
	"io/ioutil"
	"os"
	"strconv"
	"time"

	"GoFind/helper"

	"github.com/astaxie/beego"
	"github.com/astaxie/beego/toolbox"
	"github.com/gomodule/redigo/redis"
)

const henchtest = iota

func init() {
	name := "LogsTasks"     // name task name
	spec := "0/2 * * * * *" // spec sec,min,hour,day,month,week 0-6(0:sunday)
	t := new(logsTasks)

	// logs redis cache key
	t.redisKey = "syncLogsList"

	// log path;default ./logs
	if path := beego.AppConfig.String("logpath");path == ""{
		t.path = "./logs"
	}else {
		t.path = path
	}

	// file hold days,default 7 days
	if hold,err := beego.AppConfig.Int("loghold");err != nil{
		t.hold = 7
	}else {
		t.hold = hold
	}

	// just comment it
	t.addTask(name, spec)
}

type logsTasks struct {
	redisKey	string
	path 		string
	hold		int
	clearedAt	string
}

type logsParams struct {
	Logs              string   `json:"logs"`
	Note              string   `json:"note"`
}

// AddTask used to add the task to cron
func (lt *logsTasks) addTask(name string, spec string) (err error) {
	task := toolbox.NewTask(name, spec, lt.handle)
	toolbox.AddTask(name, task)
	return nil
}

// Handle mkDir on daily and slice on both hour and file size
func (lt *logsTasks) handle() error {

	conn := helper.GetRedis()
	defer conn.Close()

	lt.Write("hench","test"+strconv.Itoa(henchtest))
	return nil

	var stuList []logsParams
	var stu logsParams

	for i:=20;i>0;i--{
		s, err := redis.String(conn.Do("LPOP",lt.redisKey))
		if err == nil {
			if err := json.Unmarshal([]byte(s), &stu); err == nil {
				stuList = append(stuList, stu)
			}
		}
	}

	currentTime := time.Now().Local()
	daily := currentTime.Format("2006-01-02")
	hour := currentTime.Hour()

	// clear over date logs
	if daily != lt.clearedAt {
		lt.rmOverLogs()
		lt.clearedAt = daily
	}

	var path = lt.path+"/"+daily

	if _, err := os.Stat(path); err != nil {
		if err := os.Mkdir(path,os.ModePerm);err != nil{
			return err
		}
	}

	for _, stu := range stuList {
		filePath := path+"/"+stu.Note+"_"+strconv.Itoa(hour)+".logs"

		if file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0766);err == nil {
			file.WriteString(stu.Logs)
			file.Close()
		}
	}

	return nil
}


func (lt *logsTasks) Info(str string) error {
	return lt.Write(str,"info")
}

func (lt *logsTasks) Error(str string) error {
	return lt.Write(str,"error")
}

func (lt *logsTasks) Write(str string,note string) error {

	if note == "" { note = "write" }
	tmp := logsParams{time.Now().Local().Format("2006-01-02 15:04:05 ")+str+"\r\n",note}
	logs, err := json.Marshal(tmp);
	if err != nil { return err }

	helper.GetRedis().Do("RPUSH",lt.redisKey,logs)
	return nil
}

func (lt *logsTasks) rmOverLogs() {
	overTime := time.Now().Local().AddDate(0,0,lt.hold+1)

	files, _ := ioutil.ReadDir(lt.path)
	for _, file := range files {
		if file.IsDir() {
			if t, err := time.Parse("2018-01-01", file.Name()); err == nil{
				if overTime.Before(t) {
					os.RemoveAll(lt.path+file.Name())
				}
			}
		}
	}
}